package net.wanho.service.impl;

import cn.hutool.core.util.IdUtil;
import cn.hutool.crypto.SecureUtil;
import com.wf.captcha.ArithmeticCaptcha;
import com.wf.captcha.base.Captcha;
import lombok.RequiredArgsConstructor;
import net.wanho.contant.UserConstant;
import net.wanho.dto.LoginUserDTO;
import net.wanho.exception.CaptchaException;
import net.wanho.exception.LoginErrorException;
import net.wanho.mapper.RoleMapper;
import net.wanho.mapper.UserMapper;
import net.wanho.po.User;
import net.wanho.service.LoginService;
import net.wanho.util.JwtUtil;
import net.wanho.vo.CaptchaVo;
import net.wanho.vo.LoginVo;
import org.springframework.beans.BeanUtils;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * Author：汤小洋
 * Date：2025-09-25 11:16
 * Description：<描述>
 */
@Service
@RequiredArgsConstructor
@Transactional(rollbackFor = Exception.class)
public class LoginServiceImpl implements LoginService {

    private final UserMapper userMapper;
    private final RoleMapper roleMapper;
    private final StringRedisTemplate redisTemplate;

    @Override
    public LoginVo login(LoginUserDTO loginUserDTO) {
        /**
         * 判断用户
         */
        User user = userMapper.selectByUsername(loginUserDTO.getUsername());
        if(user == null){
            throw new LoginErrorException("用户不存在");
        }
        if(!user.getPassword().equals(SecureUtil.md5(loginUserDTO.getPassword()))){
            throw new LoginErrorException("密码错误");
        }
        if(user.getMgState()== UserConstant.STATE_DISABLE){
            throw new LoginErrorException("用户被禁用");
        }

        /**
         * 生成token
         */
        Map<String,Object> payload = new HashMap<>();
        payload.put(UserConstant.USER_ID, user.getId());
        payload.put(UserConstant.USER_NAME, user.getUsername());
        String token = JwtUtil.generate(payload);

        /**
         * 封装返回数据
         */
        LoginVo loginVo = new LoginVo();
        BeanUtils.copyProperties(user, loginVo);
        loginVo.setToken("Bearer " + token);
        loginVo.setRoleName(roleMapper.selectById(user.getRoleId()).getRoleName());

        return loginVo;
    }

    @Override
    public CaptchaVo captcha() {
        Captcha captcha = new ArithmeticCaptcha();

        // 生成一个临时用户id，对应用户的验证码
        String uuid = IdUtil.simpleUUID();
        // 将验证码保存到缓存redis中
        redisTemplate.opsForValue().set(UserConstant.CAPTCHA_PREFIX + uuid, captcha.text(), UserConstant.CAPTCHA_EXPIRE, TimeUnit.MINUTES);

        return new CaptchaVo(captcha.toBase64(), uuid);
    }

    @Override
    public LoginVo captchaLogin(LoginUserDTO loginUserDTO) {
        /**
         * 判断验证码
         */
        String key = UserConstant.CAPTCHA_PREFIX + loginUserDTO.getUuid();
        String trueCode = redisTemplate.opsForValue().get(key);
        if(ObjectUtils.isEmpty(trueCode)){
            throw new CaptchaException("验证码已过期");
        }

        // 删除验证码
        redisTemplate.delete(key);

        if (!trueCode.equals(loginUserDTO.getCode())){
            throw new CaptchaException("验证码错误");
        }

        return login(loginUserDTO);
    }
}
